//
//  RichTextCell.swift
//  SheYangBigData
//
//  Created by 叁拾叁 on 2021/3/2.
//  Copyright © 2021 叁拾叁. All rights reserved.
//

import UIKit
import WebKit

class RichTextCell: UITableViewCell {

    var currentVC: UIViewController!
    var webHeight: CGFloat = 0.0
    var webHeightClosure: ((_ height: CGFloat)->Void)?
    var progressClosure: ((_ size: Float)->Void)?
    public lazy var webView: WKWebView = {
        let config: WKWebViewConfiguration = WKWebViewConfiguration()
//        let prefer: WKPreferences = WKPreferences()
//        //设置是否支持javaScript 默认是支持的
//        prefer.javaScriptEnabled = true
//        //最小字体大小 当将javaScriptEnabled属性设置为NO时，可以看到明显的效果
//        prefer.minimumFontSize = 0
//        // 在iOS上默认为NO，表示是否允许不经过用户交互由javaScript自动打开窗口
//        prefer.javaScriptCanOpenWindowsAutomatically = true
//        config.preferences = prefer
//        // 是使用h5的视频播放器在线播放, 还是使用原生播放器全屏播放
//        config.allowsInlineMediaPlayback = true
//        //设置视频是否需要用户手动播放  设置为NO则会允许自动播放
//        config.mediaTypesRequiringUserActionForPlayback = .video
//        //设置是否允许画中画技术 在特定设备上有效
//        config.allowsPictureInPictureMediaPlayback = true
//        //设置请求的User-Agent信息中应用程序名称 iOS9后可用
//        config.applicationNameForUserAgent = "ChinaDailyForiPad"
////        config.userContentController = WKUserContentController()
////        config.selectionGranularity = WKSelectionGranularity.character
        
        //以下代码适配文本大小
//        let jsStr = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
//        //用于进行JavaScript注入
//        let wkScript = WKUserScript(source: jsStr, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
//        config.userContentController.addUserScript(wkScript)
        
        
        self.injectSwiftMethod(config)
        let web = WKWebView(frame: CGRect.zero, configuration:config)
        
        web.scrollView.bounces = false
        web.uiDelegate = self
        web.navigationDelegate = self
        web.addObserver(self, forKeyPath: "estimatedProgress", options: .new, context: nil)
        web.backgroundColor = .white
        web.scrollView.isScrollEnabled = false
        return web
    }()
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        initViews()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    deinit {
        webView.removeObserver(self, forKeyPath: "estimatedProgress")
        print("RichTextCell:  释放啦")
    }
    
    func configure(_ url: String) {
        
        loadWeb(url)
        print("webHeight\(webHeight)")
    }
    
    func initViews() {
        
        self.addSubview(self.webView)
        self.webView.snp.makeConstraints { (make) in
            make.top.equalToSuperview()
            make.left.right.equalToSuperview()
            make.height.equalTo(webHeight)
            make.bottom.equalToSuperview()
        }
    }

    // 捕获title 和进度
    open override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "estimatedProgress"
        {
            self.progressClosure?(Float(self.webView.estimatedProgress))
            if self.webView.estimatedProgress >= 1.0
            {
                self.progressClosure?(1.0)
                loadSuccess()
            }
        }
    }
    
    open func loadWeb(_ url: String){

        //以下代码适配文本大小
        let htmlContent = """
        <html>
        <head>
        <meta charset='utf-8' name='viewport' content='width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no'/>
        <style type=\"text/css\">
        img {
        max-width:100%;
        -webkit-tap-highlight-color:rgba(0,0,0,0);
        }
        </style>
        <script type=\"text/javascript\">
        </script>
        </head>
        <body>
        <div>
        <div id=\"webview_content_wrapper\">\(url)</div>
        </div>
        </body>
        </html>
        """
        webView.loadHTMLString(htmlContent, baseURL: nil)//load需在addsubview之后
    }
    
    // 注入方法名
    open func injectSwiftMethod(_ config: WKWebViewConfiguration) {
        
    }
    
    // js需要执行的swift方法
    open func swiftAction(_ name: String, _ body: Dictionary<String, Any>) {

    }
    
    // swift需要执行的js方法
    open func jsAction() {
        
    }
    
    //关闭加载方法
    open func getH5Url(_ url: String){
        
    }
    
    open func loadSuccess() {
        
    }
    
    open func loadFail() {
        
    }
}

extension RichTextCell: WKUIDelegate
{
    // 显示的一些拦截 alert等

    // 监听通过JS调用警告框
    public func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
        let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
            completionHandler()
        }))
        self.currentVC.sg_present(alert, animated: true, completion: nil)
    }
    
    // 监听通过JS调用提示框
    public func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
        let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
            completionHandler(true)
        }))
        alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in
            completionHandler(false)
        }))
        self.currentVC.sg_present(alert, animated: true, completion: nil)
    }
    
    // 监听JS调用输入框
    public func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
        // 类似上面两个方法
    }
}

extension RichTextCell: WKScriptMessageHandler
{
    // 在此js向swift传值
    public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        print("js向swift传值:\n  message.name: \(message.name)\n  message.body: \(message.body)")
        let body = message.body as! [String: Any]
        swiftAction(message.name, body)
    }
}


extension RichTextCell: WKNavigationDelegate
{
    // 在此可调用js方法
    public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        self.jsAction()
        
        if webHeight == 0 {
            
            webView.evaluateJavaScript("document.body.scrollHeight") { (result, error) in
                print("res", result, error)
                if let webHeight = result as? CGFloat {
                    self.webView.snp.updateConstraints({ (make) in
                        make.height.equalTo(webHeight)
                    })
                    self.webHeightClosure?(webHeight)
                    self.webHeight = webHeight
                }else{
                    self.webHeightClosure?(0)
                }
            }
        }
    }
    
    // 拦截url
    public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        if let url = navigationAction.request.url?.absoluteString
        {
            getH5Url(url)
        }
        decisionHandler(.allow)
    }
    
    public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        loadFail()
    }
    
    public func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        // 如果是拨打电话的url拦截
        let e = error as NSError
        if let value = e.userInfo["NSErrorFailingURLStringKey"] {
            if let vs = value as? String, vs.contains("tel://") {
                return
            }
        }
        loadFail()
    }
}

